import 'dart:typed_data';

import 'jieli_ble_ota_plugin_platform_interface.dart';

class JieliBleOtaPlugin {
  static const String writeData = "inmotion://cb/write_data";
  static const String onOtaProgressChanged = "inmotion://cb/on_ota_progress_changed";
  static const String onDeviceFirmwareStatusRequested = "inmotion://cb/on_device_firmware_status_requested";
  static const String onDeviceFirmwareStatusRequestFailed = "inmotion://cb/on_device_firmware_status_request_failed";
  static const String onRequestDisconnectLink = "inmotion://cb/link/disconnect";
  static const String onRequestConnectLink = "inmotion://cb/link/connect";
  static const String onOtaUpdateFailed = "inmotion://cb/on_ota_update_failed";
  static const String onOtaUpdateSuccess = "inmotion://cb/on_ota_update_success";

  static const String methodStart2Ota = "inmotion://jieli_ota/method_start_to_ota";
  static const String methodRequestDeviceFirmwareState = "inmotion://jieli_ota/method_request_fw_state";
  static const String methodNotifyDataReceived = "inmotion://jieli_ota/method_on_msg_received";
  static const String methodNotifyConnected = "inmotion://jieli_ota/method_on_link_connected";
  static const String methodNotifyDisconnected = "inmotion://jieli_ota/method_on_link_disconnected";

  /// 升级类型 - 下载 bootloader
  static const int updateTypeBootloader = 0;

  /// 升级类型 - 下载 app
  static const int updateTypeApp = 1;

  final DataWriteHandler _dataWriteHandler;
  final OtaCallback _otaCallback;
  final LinkLayerHandler _linkLayerHandler;

  JieliBleOtaPlugin(this._dataWriteHandler, this._otaCallback, this._linkLayerHandler) {
    JieliBleOtaPluginPlatform.instance.setDataWriteHandler(_dataWriteHandler);
    JieliBleOtaPluginPlatform.instance.setOtaCallback(_otaCallback);
    JieliBleOtaPluginPlatform.instance.setLinkLayerHandler(_linkLayerHandler);
  }

  void notifyDataReceived(Uint8List bytes) {
    JieliBleOtaPluginPlatform.instance.notifyDataReceived(bytes);
  }

  void notifyLinkConnected(String identifier, String name) {
    JieliBleOtaPluginPlatform.instance.notifyLinkConnected(identifier, name);
  }

  void notifyLinkDisconnected(String identifier, String name) {
    JieliBleOtaPluginPlatform.instance.notifyLinkDisconnected(identifier, name);
  }

  void requestDeviceFirmwareState() {
    JieliBleOtaPluginPlatform.instance.requestDeviceFirmwareState();
  }

  void start(String file) {
    JieliBleOtaPluginPlatform.instance.startOta(file);
  }

  Map<String, dynamic> getBleCommunicationUUID() {
    return {
      'write_service_uuid': '0000ae00-0000-1000-8000-00805f9b34fb',
      'write_characteristic_uuid': '0000ae01-0000-1000-8000-00805f9b34fb',
      'notify_service_uuid': '0000ae00-0000-1000-8000-00805f9b34fb',
      'notify_characteristic_uuid': '0000ae02-0000-1000-8000-00805f9b34fb',
    };
  }
}

abstract class DataWriteHandler {
  Future writeBytes(Uint8List bytes);
}

abstract class OtaCallback {
  void onOtaUpdateSuccess();

  void onOtaUpdateFailed(String code);

  void onOtaProgressChanged(int type, double progress);

  void onDeviceFirmwareStatusRequested(bool success, bool isFirmwareBroken);
}

abstract class LinkLayerHandler {
  Future disconnect();

  Future reconnect();
}
